<template>
  <div :style="'width: 100%; max-width: ' + props.width + 'px;height: ' + props.height + 'px'">
    <div v-if="inputDisabled || props.showText" :class="['image-box', imageUrl ? '' : 'bg-gray']">
      <el-image
        v-if="imageUrl !== ''"
        preview-teleported
        hide-on-click-modal
        :src="imageUrl"
        :preview-src-list="[imageUrl]"
        style="width:100%;height:100%"
        fit="scale-down"
      />
      <cc-icon
        v-else
        style="font-size: 60px;color: #9ea0a2"
        iconId="018ece4f6d31e292d623"
        title="未上传"
      />
    </div>
    <div v-else-if="!inputDisabled" class="image-edit-box">
      <el-upload :class="['cc-image', {'is-disabled': inputDisabled}]" action=""
        :disabled="inputDisabled"
        :http-request = "handleUpload"
        :show-file-list="false"
        :accept="'image/*'"
        :before-upload="handleBeforeUpload"
      >
        <cc-icon
          v-if="loading"
          :style="`font-size: ${props.iconSize}px; color: #999`"
          iconId="018dcab3d3dfd6e82393"
          class="spinner"
        />
        <span v-else-if="imageUrl && !loading">
          <img :src="imageUrl" alt />
        </span>
        <cc-icon
          v-else
          :style="`color: #999; font-size: ${props.iconSize}px`"
          iconId="018dca3b4707c4c43a2f"
        />
      </el-upload>
      <div v-if="handDraw === '1'" class="image-hand-draw">
        <cc-icon
          style="color: #26c2cf; font-size: 20px"
          iconId="018ece4f6918a49a759b"
          title="打开画板"
          @click.stop="openDraw"
        />
      </div>
    </div>

    <el-dialog
      width="500px"
      v-model="dialogVisible"
      :close-on-click-modal="false"
      append-to-body
      destroy-on-close
      draggable
      fullscreen
      class="cc-page-comp-dialog"
    >
      <template #header>
        <div class="header">
          <div class="title">画板</div>
        </div>
      </template>
      <cc-signature-pad
        v-if="dialogVisible"
        ref="signatureRef"
      />
      <template #footer>
        <el-button
          size="default"
          type="info"
          @click="dialogVisible = false"
        >取消</el-button>
        <el-button
          size="default"
          type="warning"
          @click="clearDraw"
        >清空</el-button>
        <el-button
          size="default"
          type="primary"
          @click="submitDraw"
          :loading="editLoading"
        >提交</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, nextTick, inject } from 'vue'
import { ElMessage, useDisabled, useFormItem } from "element-plus";
import api from "@/http/api";

const emit = defineEmits(['change']);
const props = defineProps({
  prop: {
    type: String,
    default: ''
  },
  width: {
    type: Number,
    default: 100
  },
  height: {
    type: Number,
    default: 100
  },
  iconSize: {
    type: Number,
    default: 28
  },
  maxSize: {
    type: Number,
    default: 100
  },
  handDraw: {
    type: String,
    default: '0'
  },
  options: Object,
  showText: Boolean
});
const formData = inject('formData');

const loading = ref(true);
const fileId = ref('');
const imageUrl = ref('');
const inputDisabled = useDisabled();
const formItem = useFormItem();

const dialogVisible = ref(false);
const editLoading = ref(false);
const signatureRef = ref();

const handleUpload = (data) => {
  return new Promise((resolve, reject) => {
    api.upload({'file': data.file, type: data.file.type}).then((res) => {
      loading.value = false;
      fileId.value = res.data.id;
      imageUrl.value = URL.createObjectURL(data.file);
      formData.value[props.prop] = res.data.id;
      emit('change');

      nextTick(() => {
        if (formItem && formItem.formItem) {
          formItem.formItem.validate('change');
        }
      });
      resolve();
    }).catch(() => {
      loading.value = false;
      reject();
    });
  });
};

const handleBeforeUpload = (file) => {
  if (loading.value) {
    ElMessage.error("图片正在上传中，请稍候再试！");
    return false;
  }
  loading.value = true;

  let isImage = file.type.includes("image");
  if (!isImage) {
    loading.value = false;
    ElMessage.error("上传文件类型必须是图片!");
    return false;
  }
  let isLtMaxSize = file.size / 1024 / 1024 < props.maxSize;
  if (!isLtMaxSize) {
    loading.value = false;
    ElMessage.error("上传图片大小不能超过 " + props.maxSize + "MB!");
    return false;
  }
  return isImage && isLtMaxSize;
};

const loadData = () => {
  if (typeof formData.value[props.prop] !== "undefined"
      && formData.value[props.prop] != null
      && formData.value[props.prop] !== '') {
    fileId.value = formData.value[props.prop];
    imageUrl.value = import.meta.env.VITE_IMAGE_PATH + fileId.value;
    loading.value = false;
  } else {
    loading.value = false;
    fileId.value = '';
    imageUrl.value = '';
  }
};

const openDraw = () => {
  dialogVisible.value = true;
};

const clearDraw = () => {
  signatureRef.value.clearSignature();
};

const submitDraw = () => {
  const signData = signatureRef.value.saveSignature();

  if (!signData.isEmpty) {
    api.upload({base64: signData.data.split(',')[1]}).then(res => {
      loading.value = false;
      fileId.value = res.data.id;
      imageUrl.value = signData.data;
      formData.value[props.prop] = res.data.id;
      emit('change');

      dialogVisible.value = false;
      nextTick(() => {
        if (formItem && formItem.formItem) {
          formItem.formItem.validate('change');
        }
      });
    });
  } else {
    ElMessage.warning("画板内容为空！");
  }
};

watch(() => formData.value[props.prop], (newVal) => {
  if ((newVal || '') === '' || (fileId.value || '') === '' || newVal !== fileId.value) {
    fileId.value = '';
    imageUrl.value = '';
    loadData();
  }
});

onMounted(() => {
  loadData();
});
</script>

<style scoped>
.cc-image {
  height: 100%;
  width: 100%;
  flex: 1;
  justify-content: center;
  align-items: center;
  display: flex;
  border: 1px dashed #c2c2c2;
}
.cc-image :deep(.el-upload) {
  display: flex;
  text-align: center;
  cursor: pointer;
  outline: 0;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}
.cc-image :deep(.el-upload span) {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.cc-image:not(.is-disabled) :deep(.el-upload) {
  cursor: pointer;
}
.cc-image:not(.is-disabled) :deep(.el-upload:hover) {
  border-color: #409EFF;
}
.cc-image img {
  max-width: 100%;
  max-height: 100%;
}
.image-box {
  border: 1px dashed #d9d9d9;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
.image-box img {
  max-width: 100%;
  max-height: 100%;
}
.cc-image :deep(.el-upload:after) {
  display: block;
  margin-top: 100%;
  content: ""
}
.image-edit-box {
  position: relative;
}
.image-hand-draw {
  position: absolute;
  top: 5px;
  right: 5px;
  cursor: pointer;
}
</style>